import os
from random import randint
import pygame
from pygame.locals import *
from pygame.time import delay
from dissipate.img import img_basic
from dissipate.sounds import Sounds, play_sound
from dissipate.sprites import Board, Element


class Manager:
    """Game manager."""
    # 游戏屏幕的大小设置为900x600像素
    __screen_size = (900, 600)
    # 使用pygame库设置屏幕模式，DOUBLEBUF是双缓冲，32是位深度
    screen = pygame.display.set_mode(__screen_size, DOUBLEBUF, 32)
    # 砖块的大小设置为50x50像素
    __brick_size = 50
    # 加载背景图片并转换为优化格式
    __bg = pygame.image.load(os.path.join(img_basic, 'bg.png')).convert()
    # 停止宽度，可能用于游戏结束或暂停的界面
    stop_width = 63
    # 当前选中的砖块位置，格式为[row, col]
    selected = [-1, -1]
    # 交换标志，可能用于交换砖块或游戏逻辑
    swap_sign = -1
    # 上一次选中的砖块位置，格式为[row, col]
    last_sel = [-1, -1]
    # 是否交换的标志，用于判断是否发生了交换
    value_swapped = False
    # 死亡地图的标志，可能用于显示或隐藏死亡相关的游戏元素
    death_sign = True
    # 消除4个砖块时选中的位置，格式为[row, col]
    boom_sel = [-1, -1]
    # 当前关卡，0表示树（可能是特殊关卡或菜单）
    level = 0
    # 玩家的金钱数量
    money = 100
    # 能量点数
    energy_num = 30
    # 数字标志，可能用于显示或隐藏数字相关的游戏元素
    num_sign = True
    # 游戏类型，0为进行中，1为通过，-1为失败，2为树
    type = 2
    # 是否重置布局的标志
    reset_mode = True
    # 每个关卡的初始步数
    init_step = 15
    # 当前游戏剩余的步数
    step = init_step
    # 玩家的得分
    score = 0
    # 中等得分的两个阈值
    min = 20
    max = 50
    # 已消除动物的数量列表，长度为6，可能代表6种不同的动物
    animal_num = [0, 0, 0, 0, 0, 0]
    # 剩余需要消除的冰块数量
    ice_num = 0
    # 成功板，继承自Board类，位置在[200, 0]
    success_board = Board(Board.success, [200, 0])
    # 失败板，继承自Board类，位置在[200, 0]
    fail_board = Board(Board.fail, [200, 0])
    # 游戏网格的高度和宽度，都是9
    height, width = 9, 9
    # 选中的行和列，初始值为5
    row, col = 5, 5
    # 冰块列表，21x21的二维列表，-1表示无冰块，1表示有冰块
    ice_list = [[-1 for _ in range(21)] for _ in range(21)]
    # 动物列表，21x21的二维列表，-2表示已消除，-1表示无动物，0-4表示不同的动物
    animal = [[-1 for _ in range(21)] for _ in range(21)]
    # 砖块的x和y位置列表，用于确定砖块在屏幕上的位置
    list_x, list_y = (__screen_size[0] - 11 * __brick_size) / 2, (__screen_size[1] - 11 * __brick_size) / 2

    def __init__(self, width, height):
        self.height = height
        self.width = width
        self.list_x = (Manager.__screen_size[0] - self.width * Manager.__brick_size) / 2
        self.list_y = (Manager.__screen_size[1] - self.height * Manager.__brick_size) / 2
        self.row, self.col = Manager.xy_rc(self.list_x, self.list_y)
        self.list_x, self.list_y = Manager.rc_xy(self.row, self.col)
        self.ice_list = [[-1 for _ in range(21)] for _ in range(21)]
        self.animal = [[-1 for _ in range(21)] for _ in range(21)]
        self.reset_animals()

    def reset_animals(self):
        """
        用于将游戏板上的动物随机重置为0到5之间的数字，
        其中0可能表示没有动物，1到5表示不同类型的动物。
        """
        # 遍历由self.row和self.col确定的起始行和列，直到高度和宽度决定的结束行和列
        for row in range(self.row, self.row + self.height):
            # 对于每一行row，遍历由self.col和self.col + self.width确定的起始列和结束列
            for col in range(self.col, self.col + self.width):
                # 为当前位置(row, col)随机分配一个动物编号，编号范围从0到5
                # randint是random模块中的一个函数，用于生成一个指定范围内的随机整数
                self.animal[row][col] = randint(0, 5)

    @staticmethod
    def rc_xy(row, col):
        """(row, col) -> (x, y)"""
        return int(Manager.list_x + (col - Manager.col) * Manager.__brick_size), int \
            (Manager.list_y + (row - Manager.row) * Manager.__brick_size)

    @staticmethod
    def xy_rc(x, y):
        """(x, y) -> (row, col)"""
        return int((y - Manager.list_y) / Manager.__brick_size + Manager.row), int \
            ((x - Manager.list_x) / Manager.__brick_size + Manager.col)

    @staticmethod
    def draw_brick(x, y):
        """Draw a brick at (x, y)."""
        brick = Element(Element.brick, (x, y))
        Manager.screen.blit(brick.image, brick.rect)

    def draw_task(self, task_animal_num, which_animal, board_position=(400, 90), animal_position=(430, 35),
                  txt_position=(455, 60)):
        """
        绘制任务板
        """
        txt_size = 24
        txt_color = (0, 0, 0)
        Board(Board.task_board, board_position).draw(self.screen)
        if which_animal == 6:
            task_animal = Element(Element.ice, animal_position)
        else:
            task_animal = Element(Element.animals[which_animal], animal_position)
        task_animal.image = pygame.transform.smoothscale(task_animal.image, (40, 40))
        task_animal.draw(self.screen)
        if which_animal == 6:
            if task_animal_num - self.ice_num <= 0:
                Board(Board.ok, (txt_position[0], txt_position[1] + 15)).draw(self.screen)
            else:
                self.load_text(str(task_animal_num - self.ice_num), txt_position, txt_size, txt_color)
        else:
            if task_animal_num - self.animal_num[which_animal] <= 0:
                Board(Board.ok, (txt_position[0], txt_position[1] + 15)).draw(self.screen)
            else:
                self.load_text(str(task_animal_num - self.animal_num[which_animal]), txt_position, txt_size, txt_color)

    def draw(self):
        """绘制背景、动物等元素。"""
        # 绘制背景
        self.screen.blit(Manager.__bg, (0, 0))
        # 显示剩余步数
        Board(Board.step_board, (0, 142)).draw(self.screen)
        tens, single = divmod(self.step, 10)
        if tens == 0:
            Board(Board.num_format % single, (790, 110)).draw(self.screen)
        else:
            Board(Board.num_format % tens, (775, 110)).draw(self.screen)
            Board(Board.num_format % single, (805, 110)).draw(self.screen)
        # 显示关卡和暂停按钮
        Board(Board.level_format % self.level, (30, 105)).draw(self.screen)
        Element(Element.stop, Element.stop_position).draw(self.screen)

        # 绘制砖块、冰块和动物
        brick_group = pygame.sprite.Group()
        animal_group = pygame.sprite.Group()
        ice_group = pygame.sprite.Group()
        for i in range(0, 21):
            for j in range(0, 21):
                x, y = Manager.rc_xy(i, j)
                if self.animal[i][j] != -1:
                    brick_group.add(Element(Element.brick, (x, y)))
                    animal_group.add(Element(Element.animals[self.animal[i][j]], (x, y)))
                if self.ice_list[i][j] != -1:
                    ice_group.add(Element(Element.ice, (x, y)))
        brick_group.draw(self.screen)
        ice_group.draw(self.screen)
        for animal_list in animal_group:
            self.screen.blit(animal_list.image, animal_list.rect)
        if self.level == 1:
            self.draw_task(10, 4)
        elif self.level == 2:
            self.draw_task(21, 1)
        elif self.level == 3:
            self.draw_task(16, 4, (300, 90), (330, 35), (360, 60))
            self.draw_task(16, 5, (500, 90), (530, 35), (560, 60))
        elif self.level == 4:
            self.draw_task(18, 5, (300, 90), (330, 35), (360, 60))
            self.draw_task(18, 2, (500, 90), (530, 35), (560, 60))
        elif self.level == 5:
            self.draw_task(28, 2, (300, 90), (330, 35), (360, 60))
            self.draw_task(28, 0, (500, 90), (530, 35), (560, 60))
        elif self.level == 6:
            self.draw_task(70, 4)
        elif self.level == 7:
            self.draw_task(36, 1)
            self.draw_task(36, 2, (300, 90), (330, 35), (360, 60))
            self.draw_task(36, 0, (500, 90), (530, 35), (560, 60))
        elif self.level == 8:
            self.draw_task(15, 6)
        elif self.level == 9:
            self.draw_task(49, 6)
        else:
            self.draw_task(39, 6)

        # 显示选择的动物
        if self.selected != [-1, -1]:
            frame_sprite = Element(Element.frame, Manager.rc_xy(self.selected[0], self.selected[1]))
            self.screen.blit(frame_sprite.image, frame_sprite.rect)

        # 显示得分
        self.load_text('得分:' + str(self.score), (300, 550), 30)
        pygame.draw.rect(self.screen, (50, 150, 50, 180), Rect(300, 570, self.score * 2, 25))
        pygame.draw.rect(self.screen, (100, 200, 100, 180), Rect(300, 570, 200, 25), 2)
        return animal_group

    def mouse_image(self):
        # 加载鼠标图片
        mouse_cursor = pygame.image.load(os.path.join(img_basic, 'mouse.png')).convert_alpha()
        mouse_x, mouse_y = pygame.mouse.get_pos()
        # 计算鼠标左上角位置
        mouse_x -= mouse_cursor.get_width() / 2
        mouse_y -= mouse_cursor.get_height() / 2
        # 绘制鼠标图片
        self.screen.blit(mouse_cursor, (mouse_x, mouse_y))

    def mouse_select(self, mousex, mousey):
        if self.type == 1:  # 已通关
            if Board.button_position[0][0] < mousex < Board.button_position[0][0] + 100 \
                    and Board.button_position[0][1] - 50 < mousey < Board.button_position[0][
                1]:  # 点击重玩按钮
                if self.energy_num < 5:
                    self.level = 0
                self.reset_mode = True
            elif Board.button_position[1][0] < mousex < Board.button_position[1][0] + 100 \
                    and Board.button_position[1][1] - 50 < mousey < Board.button_position[1][
                1]:  # 点击下一关按钮
                if self.level < 10:
                    if self.energy_num < 5:
                        self.level = 0
                    else:
                        self.level += 1
                    self.reset_mode = True
            elif 610 < mousex < 610 + 55 and 205 - 55 < mousey < 205:  # x
                self.level = 0
                self.reset_mode = True

        elif self.type == -1:  # 未通过
            if Board.button_position[1][0] < mousex < Board.button_position[1][0] + 100 \
                    and Board.button_position[1][1] - 50 < mousey < Board.button_position[1][1]:  # 点击重玩按钮
                if self.energy_num < 5:
                    self.level = 0
                self.reset_mode = True
            elif Board.button_position[0][0] < mousex < Board.button_position[0][0] + 100 \
                    and Board.button_position[0][1] - 50 < mousey < Board.button_position[0][
                1]:  # 点击再来5步按钮
                if self.money < 5:
                    self.level = 0
                else:
                    self.money -= 5
                    self.step += 5
                    self.type = 0  # 正在游戏
                    self.fail_board = Board(Board.fail, [200, 0])
            elif 610 < mousex < 610 + 55 and 205 - 55 < mousey < 205:
                self.level = 0
                self.reset_mode = True

        elif self.type == 0:  # 游戏中
            if self.list_x < mousex < self.list_x + Manager.__brick_size * self.width \
                    and self.list_y < mousey < self.list_y + Manager.__brick_size * self.height:
                mouse_selected = Manager.xy_rc(mousex, mousey)
                if self.animal[mouse_selected[0]][mouse_selected[1]] != -1:
                    play_sound(Sounds.CLICK)
                    self.selected = mouse_selected
                    if (self.last_sel[0] == self.selected[0]
                        and abs(self.last_sel[1] - self.selected[1]) == 1) \
                            or (self.last_sel[1] == self.selected[1]
                                and abs(self.last_sel[0] - self.selected[0]) == 1):
                        self.swap_sign = 1  # 有效移动，交换
            elif Element.stop_position[0] < mousex < Element.stop_position[0] + self.stop_width and \
                    Element.stop_position[1] < mousey < Element.stop_position[1] + self.stop_width:  # 点击退出按钮
                play_sound(Sounds.CLICK_BUTTON)
                self.level = 0
                self.reset_mode = True
            else:
                self.selected = [-1, -1]

    def swap(self, group):
        """在棋盘上交换两个选定的动物。"""
        last_sprite = None
        selected_sprite = None
        if self.swap_sign == -1:  # 尚未交换
            self.last_sel = self.selected
        if self.swap_sign == 1:
            last_x, last_y = Manager.rc_xy(self.last_sel[0], self.last_sel[1])
            sel_x, sel_y = Manager.rc_xy(self.selected[0], self.selected[1])
            if self.last_sel[0] == self.selected[0]:  # 纵向交换
                for animal_list in group:
                    if animal_list.rect.topleft == (last_x, last_y):
                        last_sprite = animal_list
                        last_sprite.speed = [self.selected[1] - self.last_sel[1], 0]
                    elif animal_list.rect.topleft == (sel_x, sel_y):
                        selected_sprite = animal_list
                        selected_sprite.speed = [self.last_sel[1] - self.selected[1], 0]
            else:  # 横向交换
                for animal_list in group:
                    if animal_list.rect.topleft == (last_x, last_y):
                        last_sprite = animal_list
                        last_sprite.speed = [0, self.selected[0] - self.last_sel[0]]
                    elif animal_list.rect.topleft == (sel_x, sel_y):
                        selected_sprite = animal_list
                        selected_sprite.speed = [0, self.last_sel[0] - self.selected[0]]
            while last_sprite and last_sprite.speed != [0, 0]:
                delay(5)
                self.draw_brick(last_x, last_y)
                self.draw_brick(sel_x, sel_y)
                last_sprite.move(last_sprite.speed)
                selected_sprite.move(selected_sprite.speed)
                self.screen.blit(last_sprite.image, last_sprite.rect)
                self.screen.blit(selected_sprite.image, selected_sprite.rect)
                pygame.display.flip()

            self.swap_values()
            if self.eliminate_animals():
                self.step -= 1
            else:
                self.swap_values()
            self.value_swapped = False
            self.boom_sel = self.selected
            self.swap_sign = -1
            self.selected = [-1, -1]

    def swap_values(self):
        """交换值。"""
        (xl, yl), (xc, yc) = self.last_sel, self.selected
        self.animal[xl][yl], self.animal[xc][yc] = self.animal[xc][yc], self.animal[xl][yl]

    def load_text(self, text, position, txt_size, txt_color=(255, 255, 255)):
        """显示给定位置、大小和颜色的文本。"""
        my_font = pygame.font.SysFont("黑体", txt_size)
        text_screen = my_font.render(text, True, txt_color)
        self.screen.blit(text_screen, position)

    def death_map(self):
        """检查是否没有有效的移动。"""
        for i in range(self.row, self.row + self.height):
            for j in range(self.col, self.col + self.width):
                if self.animal[i][j] != -1:
                    if self.animal[i][j] == self.animal[i][j + 1]:
                        if (self.animal[i][j] in [self.animal[i - 1][j - 1], self.animal[i + 1][j - 1]] and
                            self.animal[i][j - 1] != -1) or (
                                self.animal[i][j] in [self.animal[i - 1][j + 2], self.animal[i + 1][j + 2]] and
                                self.animal[i][j + 2] != -1):
                            self.death_sign = False
                            break
                    if self.animal[i][j] == self.animal[i + 1][j]:
                        if (self.animal[i][j] in [self.animal[i - 1][j - 1], self.animal[i - 1][j + 1]] and
                            self.animal[i - 1][j] != -1) or (
                                self.animal[i][j] in [self.animal[i + 2][j - 1], self.animal[i + 2][j + 1]] and
                                self.animal[i + 2][j] != -1):
                            self.death_sign = False
                            break
                    else:
                        if self.animal[i - 1][j - 1] == self.animal[i][j]:
                            if (self.animal[i][j] == self.animal[i - 1][j + 1] and self.animal[i - 1][j] != -1) or (
                                    self.animal[i][j] == self.animal[i + 1][j - 1] and self.animal[i][j - 1] != -1):
                                self.death_sign = False
                                break
                        if self.animal[i][j] == self.animal[i + 1][j + 1]:
                            if (self.animal[i][j] == self.animal[i - 1][j + 1] and self.animal[i][j + 1] != -1) \
                                    or (self.animal[i][j] == self.animal[i + 1][j - 1] and self.animal[i + 1][j] != -1):
                                self.death_sign = False
                                break
        if self.death_sign:
            delay(500)
            Element(Element.none_animal, (230, 150)).draw(self.screen)
            pygame.display.flip()
            delay(500)
            temp = [self.step, self.score, self.animal_num, self.ice_num, self.energy_num]
            self.reset_mode = True
            self.set_level_mode(self.level)
            self.step = temp[0]
            self.score = temp[1]
            self.animal_num = temp[2]
            self.ice_num = temp[3]
            self.energy_num = temp[4]
        else:
            self.death_sign = True

    def exists_left(self, i, j, num):
        """检查 (i, j) 左边是否至少有 {num} 个连续的相同动物。"""
        for t in range(0, num):
            if self.animal[i][j] != self.animal[i][j - t] or self.animal[i][j] < 0:
                return False
        return True

    def exists_right(self, i, j, num):
        """检查 (i, j) 右边是否至少有 {num} 个连续的相同动物。"""
        for t in range(0, num):
            if self.animal[i][j] != self.animal[i][j + t] or self.animal[i][j] < 0:
                return False
        return True

    def exists_up(self, i, j, num):
        """检查 (i, j) 上方是否至少有 {num} 个连续的相同动物。"""
        for t in range(0, num):
            if self.animal[i][j] != self.animal[i - t][j] or self.animal[i][j] < 0:
                return False
        return True

    def exists_down(self, i, j, num):
        """检查 (i, j) 下方是否至少有 {num} 个连续的相同动物。"""
        for t in range(0, num):
            if self.animal[i][j] != self.animal[i + t][j] or self.animal[i][j] < 0:
                return False
        return True

    def change_left(self, i, j, num):
        """改变动物的左侧。"""
        self.value_swapped = True
        self.score += num
        for k in range(0, int(num)):
            self.animal[i][j - k] = -2

    def change_right(self, i, j, num):
        """改变动物的右侧。"""
        self.value_swapped = True
        self.score += num
        for k in range(0, num):
            self.animal[i][j + k] = -2

    def change_up(self, i, j, num):
        """改变动物上方。"""
        self.value_swapped = True
        self.score += num
        for k in range(0, num):
            self.animal[i - k][j] = -2

    def change_down(self, i, j, num):
        """改变动物下方。"""
        self.value_swapped = True
        self.score += num
        for k in range(0, num):
            self.animal[i + k][j] = -2

    def eliminate_animals(self):
        """消除动物。"""
        score_level = self.score
        self.value_swapped = False

        for i in range(self.row, self.row + self.height):
            for j in range(self.col, self.col + self.width):
                if self.exists_right(i, j, 5):
                    self.value_swapped = True
                    if self.exists_down(i, j + 2, 3):
                        self.animal_num[self.animal[i][j]] += 7
                        Sounds.eliminate(5)  # 消除音效 5
                        self.change_right(i, j, 5)
                        self.change_down(i, j + 2, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_right(i, j, 5)
                elif self.exists_right(i, j, 4):
                    self.value_swapped = True
                    if self.exists_down(i, j + 1, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_right(i, j, 4)
                        self.change_down(i, j + 1, 3)
                    elif self.exists_down(i, j + 2, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_right(i, j, 4)
                        self.change_down(i, j + 2, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 4
                        Sounds.eliminate(2)  # 消除音效 2
                        self.change_right(i, j, 4)
                elif self.exists_right(i, j, 3):
                    self.value_swapped = True
                    if self.exists_down(i, j, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_right(i, j, 3)
                        self.change_down(i, j, 3)
                    elif self.exists_down(i, j + 1, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_right(i, j, 3)
                        self.change_down(i, j + 1, 3)
                    elif self.exists_down(i, j + 2, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_right(i, j, 3)
                        self.change_down(i, j + 2, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 3
                        Sounds.eliminate(1)  # 消除音效 1
                        self.change_right(i, j, 3)
                elif self.exists_down(i, j, 5):
                    self.value_swapped = True
                    if self.exists_right(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 7
                        Sounds.eliminate(5)  # 消除音效 5
                        self.change_down(i, j, 5)
                        self.change_right(i + 2, j, 3)
                    elif self.exists_left(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 7
                        Sounds.eliminate(5)  # 消除音效 5
                        self.change_down(i, j, 5)
                        self.change_left(i + 2, j, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 5)
                elif self.exists_down(i, j, 4):
                    self.value_swapped = True
                    if self.exists_left(i + 1, j, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 4)
                        self.change_left(i + 1, j, 3)
                    elif self.exists_right(i + 1, j, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 4)
                        self.change_right(i + 1, j, 3)
                    elif self.exists_left(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 4)
                        self.change_left(i + 2, j, 3)
                    elif self.exists_right(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 4)
                        self.change_right(i + 2, j, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 4
                        Sounds.eliminate(2)  # 消除音效 2
                        self.change_down(i, j, 4)
                elif self.exists_down(i, j, 3):
                    self.value_swapped = True
                    if self.exists_left(i + 1, j, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 3)
                        self.change_left(i + 1, j, 3)
                    elif self.exists_right(i + 1, j, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 3)
                        self.change_right(i + 1, j, 3)
                    elif self.exists_left(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 3)
                        self.change_left(i + 2, j, 3)
                    elif self.exists_right(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 3)
                        self.change_right(i + 2, j, 3)
                    elif self.exists_left(i + 2, j, 2) and self.exists_right(i + 2, j, 2):
                        self.animal_num[self.animal[i][j]] += 5
                        Sounds.eliminate(3)  # 消除音效 3
                        self.change_down(i, j, 3)
                        self.change_left(i + 2, j, 2)
                        self.change_right(i + 2, j, 2)
                    elif self.exists_left(i + 2, j, 2) and self.exists_right(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 3)
                        self.change_left(i + 2, j, 2)
                        self.change_right(i + 2, j, 3)
                    elif self.exists_left(i + 2, j, 3) and self.exists_right(i + 2, j, 2):
                        self.animal_num[self.animal[i][j]] += 6
                        Sounds.eliminate(4)  # 消除音效 4
                        self.change_down(i, j, 3)
                        self.change_left(i + 2, j, 3)
                        self.change_right(i + 2, j, 2)
                    elif self.exists_left(i + 2, j, 3) and self.exists_right(i + 2, j, 3):
                        self.animal_num[self.animal[i][j]] += 7
                        Sounds.eliminate(5)  # 消除音效 5
                        self.change_down(i, j, 3)
                        self.change_left(i + 2, j, 3)
                        self.change_right(i + 2, j, 3)
                    else:
                        self.animal_num[self.animal[i][j]] += 3
                        Sounds.eliminate(1)  # 消除音效 1
                        self.change_down(i, j, 3)

        self.fall_animal()
        score_level = self.score - score_level  # 计分级别

        # 显示 & 朗读：好，棒，了不起，极好，令人难以置信
        if score_level < 5:
            return self.value_swapped
        if score_level < 8:  # 5 好
            Sounds.score_level(0)
            Element(Element.score_level[0], (350, 250)).draw(self.screen)
            pygame.display.flip()
            delay(500)
        elif score_level < 10:  # 8 棒
            Sounds.score_level(1)
            Element(Element.score_level[1], (350, 250)).draw(self.screen)
            pygame.display.flip()
            delay(500)
        elif score_level < 15:  # 10 了不起
            Sounds.score_level(2)
            Element(Element.score_level[2], (350, 250)).draw(self.screen)
            pygame.display.flip()
            delay(500)
        elif score_level < 20:  # 15 极好
            Sounds.score_level(3)
            Element(Element.score_level[3], (350, 250)).draw(self.screen)
            pygame.display.flip()
            delay(500)
        elif score_level >= 20:  # 20 令人难以置信
            Sounds.score_level(4)
            Element(Element.score_level[4], (350, 250)).draw(self.screen)
            pygame.display.flip()
            delay(500)

        return self.value_swapped  # 返回交换值标记

    def fall_animal(self):
        """动物下落动画。"""
        clock = pygame.time.Clock()
        position = []
        ice_position = []

        # 收集需要下落的动物的位置
        for i in range(self.row, self.row + self.height):
            for j in range(self.col, self.col + self.width):
                if self.animal[i][j] == -2:
                    x, y = self.rc_xy(i, j)
                    position.append((x, y))
                    if self.ice_list[i][j] == 1:
                        ice_position.append((x, y))

        # 下落动画
        if position:
            for index in range(0, 9):
                clock.tick(20)
                for pos in position:
                    self.draw_brick(pos[0], pos[1])
                    if pos in ice_position:
                        Element(Element.ice_format % index, (pos[0], pos[1])).draw(self.screen)
                    Element(Element.boom_format % index, (pos[0], pos[1])).draw(self.screen)
                    pygame.display.flip()

        # 实现下落
        for i in range(self.row, self.row + self.height):
            brick_position = []
            fall_animal_list = []
            speed = [0, 1]

            # 收集需要下落的动物的位置信息
            for j in range(self.col, self.col + self.width):
                if self.animal[i][j] == -2:
                    x, y = self.rc_xy(i, j)
                    if self.ice_list[i][j] == 1:
                        play_sound(Sounds.ICE_BREAKING)
                        self.ice_num += 1
                        self.ice_list[i][j] = -1

                    brick_position.append((x, y))

                    # 收集需要下落的动物的信息
                    for m in range(i, self.row - 1, -1):
                        if self.animal[m - 1][j] != -1:
                            x, y = self.rc_xy(m - 1, j)
                            brick_position.append((x, y))
                            animal = Element(Element.animals[self.animal[m - 1][j]], (x, y))
                            fall_animal_list.append(animal)
                            self.animal[m][j] = self.animal[m - 1][j]
                        else:
                            self.animal[m][j] = randint(0, 5)
                            break

            # 动物下落实现
            while speed != [0, 0] and fall_animal_list:
                for position in brick_position:
                    self.draw_brick(position[0], position[1])
                for animal_sprite in fall_animal_list:
                    animal_sprite.move(speed)
                    animal_sprite.draw(self.screen)
                    speed = animal_sprite.speed
                pygame.display.flip()

    def judge_next(self, tp, score):
        """判断是否达到下一关。"""
        if tp == 1:  # 通过
            self.load_fns_window(score)
        elif tp == -1:  # 失败
            self.load_fail_window()

    def load_fail_window(self):
        """显示失败界面和按钮。"""
        sound_sign = 0
        step_add = Board(Board.step_add, Board.button_position[0])  # 左侧：再来5步
        retry = Board(Board.replay, Board.button_position[1])  # 右侧：重玩
        self.screen.blit(self.fail_board.image, self.fail_board.rect)  # 失败界面
        self.screen.blit(step_add.image, step_add.rect)
        self.screen.blit(retry.image, retry.rect)
        while self.fail_board.speed != [0, 0]:
            self.draw()
            self.screen.blit(self.fail_board.image, self.fail_board.rect)
            self.fail_board.move()
            pygame.display.flip()
            if sound_sign == 0:
                play_sound(Sounds.BOARD_SOUND)
                sound_sign = 1

    def load_fns_window(self, score):
        """显示成功界面、分数和按钮。"""
        sound_sign = 0
        replay = Board(Board.replay, Board.button_position[0])  # 左侧：重玩
        self.screen.blit(self.success_board.image, self.success_board.rect)  # 成功界面
        if self.level < 10:  # 如果不是最后一关
            next_level = Board(Board.next, Board.button_position[1])  # 右侧：下一关
            self.screen.blit(next_level.image, next_level.rect)
        self.screen.blit(replay.image, replay.rect)
        while self.success_board.speed != [0, 0]:
            self.draw()
            self.screen.blit(self.success_board.image, self.success_board.rect)
            self.success_board.move()
            pygame.display.flip()
            if sound_sign == 0:
                play_sound(Sounds.BOARD_SOUND)
                sound_sign = 1
        self.displayStars(score)  # 显示星星
        # 金币
        self.load_text(str(self.score * 2), (Board.starts_position[0][0] + 75, Board.starts_position[0][0] + 46), 20,
                       (0, 0, 0))

    def displayStars(self, score):
        """根据分数显示星星。"""
        star1 = Board(Board.stars, Board.starts_position[0])
        star2 = Board(Board.stars, Board.starts_position[1])
        star3 = Board(Board.stars, Board.starts_position[2])
        if 0 <= score < self.min:
            self.load_text('1', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))
            self.screen.blit(star1.image, star1.rect)
        elif self.min <= score <= self.max:
            self.load_text('2', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))
            self.screen.blit(star1.image, star1.rect)
            self.screen.blit(star2.image, star2.rect)
        elif score > self.max:
            self.load_text('5', (Board.starts_position[1][0] + 48, Board.starts_position[1][1] + 35), 20, (0, 0, 0))
            self.screen.blit(star1.image, star1.rect)
            self.screen.blit(star2.image, star2.rect)
            self.screen.blit(star3.image, star3.rect)
        pygame.display.flip()

    def set_level_mode(self, level):
        """设置关卡模式及其步骤。"""
        self.level = level
        if self.reset_mode:  # 如果需要重置模式
            self.num_sign = True
            if level == 1:
                self.__init__(7, 7)
                self.animal[7][9] = self.animal[7][10] = self.animal[7][11] = self.animal[8][10] = self.animal[11][7] = \
                    self.animal[11][13] = self.animal[12][7] = self.animal[12][8] = self.animal[12][12] = \
                    self.animal[12][13] = \
                    self.animal[13][7] = self.animal[13][8] = self.animal[13][9] = self.animal[13][11] = \
                    self.animal[13][12] = \
                    self.animal[13][13] = -1
                self.init_step = 17  # 初始步骤17
            elif level == 2:
                self.__init__(4, 8)
                self.init_step = 16  # 初始步骤16
            elif level == 3:
                self.__init__(7, 7)
                self.init_step = 18  # 初始步骤18
            elif level == 4:
                self.__init__(9, 7)
                row, col = self.row, self.col
                self.animal[row][col] = self.animal[row][col + 7] = self.animal[row][col + 8] = self.animal[row + 1][
                    col + 8] = \
                    self.animal[row + 5][col] = self.animal[row + 6][col] = self.animal[row + 6][col + 1] = \
                    self.animal[row + 6][col + 8] = -1
                self.init_step = 20
            elif level == 5:
                self.__init__(8, 9)
                row, col = self.row, self.col
                self.animal[row][col + 7] = self.animal[row + 2][col] = self.animal[row + 5][col] = \
                    self.animal[row + 3][col + 7] = \
                    self.animal[row + 6][col + 7] = self.animal[row + 8][col] = -1
                self.init_step = 20
            elif level == 6:
                self.__init__(9, 9)
                row, col = self.row, self.col
                self.animal[row][col] = self.animal[row][col + 8] = self.animal[row + 2][col + 4] = \
                    self.animal[row + 3][col + 2] = \
                    self.animal[row + 3][col + 6] = self.animal[row + 8][col] = self.animal[row + 8][col + 8] = -1
                for i in range(row + 4, row + 6):
                    for j in range(col + 3, col + 6):
                        self.animal[i][j] = -1
                self.init_step = 28
            elif level == 7:
                self.__init__(9, 9)
                row, col = self.row, self.col
                for i in range(row, row + 9):
                    self.animal[i][col + 4] = -1
                for j in range(col, col + 4):
                    self.animal[row + 3][j] = -1
                for j in range(col + 5, col + 9):
                    self.animal[row + 5][j] = -1
                self.init_step = 25
            elif level == 8:
                self.__init__(7, 8)
                row, col = self.row, self.col
                for i in range(row + 2, row + 5):
                    for j in range(col + 1, col + 6):
                        self.ice_list[i][j] = 1
                self.init_step = 21
            elif level == 9:
                self.__init__(9, 9)
                row, col = self.row, self.col
                self.animal[row][col + 4] = self.animal[row + 4][col] = self.animal[row + 4][col + 8] = \
                    self.animal[row + 8][col + 4] = -1
                for i in range(row + 1, row + 8):
                    for j in range(col + 1, col + 8):
                        self.ice_list[i][j] = 1
                self.init_step = 35
            else:
                self.__init__(9, 9)
                row, col = self.row, self.col
                for i in range(row, row + 2):
                    for j in range(col, col + 9):
                        self.animal[i][j] = -1
                self.animal[row][col + 4] = randint(0, 5)
                self.animal[row + 1][col + 2] = randint(0, 5)
                self.animal[row + 1][col + 4] = randint(0, 5)
                self.animal[row + 1][col + 6] = randint(0, 5)
                self.animal[row + 2][col + 1] = self.animal[row + 3][col + 1] = self.animal[row + 2][col + 3] = \
                    self.animal[row + 3][col + 3] = \
                    self.animal[row + 2][col + 5] = self.animal[row + 3][col + 5] = self.animal[row + 2][col + 7] = \
                    self.animal[row + 3][col + 7] = self.animal[row + 8][col] = self.animal[row + 8][col + 8] = -1
                for i in range(row + 4, row + 8):
                    for j in range(col, col + 9):
                        self.ice_list[i][j] = 1
                self.ice_list[row + 2][col + 4] = self.ice_list[row + 3][col + 2] = self.ice_list[row + 3][col + 4] = \
                    self.ice_list[row + 3][col + 6] = 1
                self.init_step = 40
            self.type = 0
            self.energy_num -= 5
            self.success_board = Board(Board.success, [200, 0])  # 成功的面板
            self.fail_board = Board(Board.fail, [200, 0])  # 失败的面板
            self.step = self.init_step
            self.score = 0
            self.animal_num = [0, 0, 0, 0, 0, 0]
            self.ice_num = 0
            self.reset_mode = False

    def num_add(self):
        """增加得分"""
        if self.num_sign:
            self.money += self.score * 2
            if self.score < self.min:
                self.energy_num += 1
            elif self.score < self.max:
                self.energy_num += 2
            else:
                self.energy_num += 5
            self.num_sign = False

    def judge_level(self):
        """检查关卡是否通过"""
        if self.step <= 0:
            self.type = -1  # 游戏结束
        if self.level == 1:
            if self.animal_num[4] >= 10:  # L1: 10 只青蛙
                self.type = 1  # 通过第一关
                self.num_add()
        elif self.level == 2:
            if self.animal_num[1] >= 21:  # L2: 21 只熊
                self.type = 1  # 通过第二关
                self.num_add()
        elif self.level == 3:
            if self.animal_num[4] >= 16 and self.animal_num[5] >= 16:  # L3: 16 只青蛙和 16 头牛
                self.type = 1  # 通过第三关
                self.num_add()
        elif self.level == 4:
            if self.animal_num[5] >= 18 and self.animal_num[2] >= 18:  # L4: 18 头牛和 18 只小鸡
                self.type = 1  # 通过第四关
                self.num_add()
        elif self.level == 5:
            if self.animal_num[2] >= 28 and self.animal_num[0] >= 28:  # L5: 28 只小鸡和 28 只狐狸
                self.type = 1  # 通过第五关
                self.num_add()
        elif self.level == 6:
            if self.animal_num[4] >= 70:  # L6: 70 只青蛙
                self.type = 1  # 通过第六关
                self.num_add()
        elif self.level == 7:
            if self.animal_num[2] >= 36 and self.animal_num[1] >= 36 \
                    and self.animal_num[0] >= 36:  # L7: 36 只小鸡、36 只熊和 36 只狐狸
                self.type = 1  # 通过第七关
                self.num_add()
        elif self.level == 8:
            if self.ice_num >= 15:  # L8: 15 冰块
                self.type = 1  # 通过第八关
                self.num_add()
        elif self.level == 9:
            if self.ice_num >= 49:  # L9: 49 冰块
                self.type = 1  # 通过第九关
                self.num_add()
        else:
            if self.ice_num >= 39:  # L10: 39 冰块
                self.type = 1  # 通过第十关
                self.num_add()

        self.judge_next(self.type, self.score)
